<html>

<head>
  <script src="./konva.min.js"></script>
  <meta charset="utf-8" />
  <title>Konva Image Demo</title>
  <style>
    body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #f0f0f0;
    }
  </style>
</head>

<body>
 
  <div id="container"></div>
  <script>

      var width = window.innerWidth;
      var height = window.innerHeight;

      var stage = new Konva.Stage({
        container: 'container',
        width: width,
        height: height,
      });

      var layer = new Konva.Layer();
      stage.add(layer);




      // function to generate a list of "targets" (circles)
      function generateTargets() {
        var number = 10;
        var result = [];
        while (result.length < number) {
          result.push({
            id: 'target-' + result.length,
            x: stage.width() * Math.random(),
            y: stage.height() * Math.random(),
          });
        }
        return result;
      }

    

      // function to generate arrows between targets
      function generateConnectors() {
        var number = 10;
        var result = [];
        while (result.length < number) {
          var from = 'target-' + Math.floor(Math.random() * targets.length);
          var to = 'target-' + Math.floor(Math.random() * targets.length);
          if (from === to) {
            continue;
          }
          result.push({
            id: 'connector-' + result.length,
            from: from,
            to: to,
          });
        }
        return result;
      }

      function getConnectorPoints(from, to) {
        const dx = to.x - from.x;
        const dy = to.y - from.y;
        let angle = Math.atan2(-dy, dx);

        const radius = 50;

        return [
          from.x + -radius * Math.cos(angle + Math.PI),
          from.y + radius * Math.sin(angle + Math.PI),
          to.x + -radius * Math.cos(angle),
          to.y + radius * Math.sin(angle),
        ];
      }

     
      
      // update all objects on the canvas from the state of the app
      function updateObjects() {
        targets.forEach((target) => {
          var node = layer.findOne('#' + target.id);
          node.x(target.x);
          node.y(target.y);
        });
        connectors.forEach((connect) => {
          var line = layer.findOne('#' + connect.id);
        
          var fromNode = layer.findOne('#' + connect.from);
          var toNode = layer.findOne('#' + connect.to);

          const points = getConnectorPoints(
            fromNode.position(),
            toNode.position()
          );
          
          line.points(points);
        });
      }

      var targets = generateTargets();
      var connectors = generateConnectors();
    


      // generate nodes for the app
      connectors.forEach((connect) => {
        var line = new Konva.Arrow({
          stroke: 'black',
          id: connect.id,
          fill: 'black',
        });
        layer.add(line);
      });

      targets.forEach((target) => {
        var node = new Konva.Circle({
          id: target.id,
          fill: Konva.Util.getRandomColor(),
          radius: 20 + Math.random() * 20,
          shadowBlur: 10,
          draggable: true,
        });
        layer.add(node);

        node.on('dragmove', () => {
       
          // mutate the state
          target.x = node.x();
          target.y = node.y();

          // update nodes from the new state
          updateObjects();
        });
      });
      

      updateObjects();

  </script>
</body>

</html>